home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / CC_C / 0924.ZIP / SCANF < prev    next >
Text File  |  1988-01-10  |  3KB  |  95 lines

  1.  
  2. /* SCANF/FSCANF/SSCANF FUNCTIONS - 16 BIT INPUT    ONLY */
  3.  
  4. scanf (fs) int *fs;
  5.      { int getc(), ungetc(); return _ffin (stdin, fs, getc, ungetc); }
  6. fscanf (fs) int    *fs;
  7.      { int getc(), ungetc(); return _ffin(*fs,    --fs, getc, ungetc); }
  8. sscanf (fs) int    *fs;
  9.      { int _mgt(), _mungt(); return _ffin(fs,    --fs, _mgt, _mungt); }
  10.  
  11. _ffin (fp, pp, read, ungetc)
  12.   char *fp, **pp; int (*read)(), (*ungetc)();
  13.      {    static int bb, base, value, asflag, sflag,
  14.            ch, temp, i,    count, width;
  15.     static char *ff, c; int    _ffgd();
  16.  
  17.     ff = *pp--; count = 0;
  18.     while (c = *ff++)
  19.     {   if (isspace    (c)) continue;
  20.         if (c != '%')
  21.         {    while (isspace (ch = (*read) (fp)));
  22.         if (ch == c) continue;
  23.         else return (ch    == EOF)    ? EOF :    count; }
  24.         sflag = asflag = 0;
  25.         if ((*ff) == '*') {    ++asflag; ++ff;    }
  26.         width = isdigit (*ff) ? 0 :    -1;
  27.         if (width == 0)
  28.         {    while ((c = *ff) >= '0'    && c <=    '9')
  29.         {  width = width * 10 +    (c - '0'); ++ff; } }
  30.  
  31.         switch ( toupper (c    = *ff++))
  32.         {  case 'D':
  33.            case 'U': base =    10; goto decode;
  34.            case 'O': base =    8;  goto decode;
  35.            case 'X': base =    16;
  36.            decode:
  37.          bb = 0; while (isspace    (ch = (*read) (fp)));
  38.          if (ch    == EOF)    return EOF;
  39.          if (width && (ch == '+' || ch == '-'))
  40.          {  if (ch == '-') ++sflag;
  41.             ch = (*read) (fp); --width;    }
  42.          if (width && base == 16 && ch == '0')
  43.          {  temp = (*read) (fp); --width;
  44.             if (toupper    (temp) == 'X' && width)
  45.             {  ch = (*read) (fp); --width; }
  46.             else
  47.             {  (*ungetc) (temp,    fp); ++width; }    }
  48.          if ((value = _ffgd(ch,    base)) == -1) return count;
  49.          while (width && (value    != -1))
  50.          {  bb = bb * base + value;
  51.             ch = (*read) (fp); --width;
  52.             value = _ffgd (ch, base); }
  53.          (*ungetc) (ch,    fp);
  54.          if (sflag) bb = - bb;
  55.          if (!asflag) {    * (int *) (*pp)    = bb; ++count; --pp; }
  56.          break;
  57.  
  58.            case 'S':
  59.          while (isspace    (ch = (*read) (fp)));
  60.          if (ch    == EOF)    return EOF;
  61.          while (width && ch != ' ' && ch != '\t' && ch != '\r'
  62.             && ch != '\n' && ch != EOF)
  63.          {  if (!asflag) *(*pp)++ = ch;
  64.             ch = (*read) (fp); --width;    }
  65.          (*ungetc) (ch,    fp);
  66.          if (!asflag)
  67.          {  *(*pp) = '\0'; ++count; --pp; }
  68.          break;
  69.  
  70.            case 'C':
  71.          if ((ch = (*read) (fp)) == EOF) return    EOF;
  72.          else if (!asflag) { *(*pp) = ch; ++count; --pp; }
  73.          break;
  74.  
  75.            default:    return count;
  76.        } }
  77.  
  78.        return count;
  79.  
  80.     } /* End of _ffin */
  81.  
  82.  
  83. /* Utilities for scanf and sscanf */
  84.  
  85. _ffgd (ch, base)
  86.      {     if (ch    >= '0' && ch <=    '9') ch    -= '0';
  87.      else if (isalpha (ch =    toupper    (ch))) ch -= ('A' - 10);
  88.      else  return -1;
  89.      return    (ch < base) ? ch : -1; }
  90.  
  91. _mgt (s) char **s; {  return (*(*s) != '\0') ? *(*s)++ : EOF; }
  92.  
  93. _mungt (c, s) int c; char **s; { --(*s);  return c; }
  94.  
  95.